home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
nan_news
/
toolkit
/
ach2tb.prg
< prev
next >
Wrap
Text File
|
1991-08-15
|
27KB
|
645 lines
/*
* File......: ACH2TB.PRG
* Author....: Steve Kolterman
* CIS ID....: 76320,37
* Date......: $Date: 15 Aug 1991 23:17:48 $
* Revision..: $Revision: 1.2 $
* Log file..: $Logfile: E:/nanfor/src/ach2tb.prv $
*
* This is an original work by Steve Kolterman and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* $Log: E:/nanfor/src/ach2tb.prv $
*
* Rev 1.2 15 Aug 1991 23:17:48 GLENN
* Last minute fix sent in by Steve Kolterman
*
* Rev 1.1 15 Aug 1991 23:06:16 GLENN
* Forest Belt proofread/edited/cleaned up doc
*
* Rev 1.0 14 Jun 1991 04:14:14 GLENN
* Initial revision.
*
*/
/* $DOC$
* $FUNCNAME$
* FT_Ach2tb()
* $ONELINER$
* Replace ACHOICE() with a Tbrowse object
* $CATEGORY$
* Menus/Prompts
* $SYNTAX$
* FT_Ach2tb( <nToprow>,<nTopcol> [, <nBotrow> ][, <nBotcol> ],<aArray>, ;
* [ <cBoxtype> ],[ <cBoxcolor> ],[ <cBoxtitle> ],[ <nTitlePos> ], ;
* [ <cUselcolor> ],[ <cTitlecolor> ],[ <cBarcolor> ],[ <cHkcolor> ], ;
* [ <cShadow> ],[ <lExecute> ],[ <nMsgrow> ],[ <nMsgcol> ], ;
* [ <cMsgcolor> ],[cElevbar],[cEbarcolor],[ <cEbarside> ], ;
* [ <cNoSelcolor> ],[ <cTagch> ],[ <nStartelem> ],[ <lRestscrn> ], ;
* [ <nTimeout> ],[ <bUserfunc> ] )
* -> nOption
* $ARGUMENTS$
* <nToprow> is the top row of the box to be drawn. Required.
*
* <nTopcol> is the top column of the box to be drawn. Required.
*
* <nBotrow> is the bottom row of the box to be drawn. The default is
* <nToprow>+Len(<aArray>)+1 or maxrow()-2, whichever is less.
*
* <nBotcol> is the bottom column of the box to be drawn. The default
* is <nTopcol>+width of the widest element in <aArray>+2.
*
* <aArray> is the array of options to present to the user. Each
* element can hold as many as five subelements, or as few as one.
* Required. Additional documentation below, in "Description."
*
* <cBoxtype> is the type of box to draw. Uses DispBox(). The
* default is a double-line box.
*
* <cBoxcolor> is the color with which to draw the box. The default is
* Setcolor().
*
* <cBoxtitle> is title of the box drawn on <nToprow>. The default is
* no title.
*
* <nTitlepos> is the starting column position (to the right of
* <nTopcol>) at which to draw <cBoxtitle>. The default is 1.
*
* <cUselcolor> is the color with which to draw unselected options.
* The default is Setcolor().
*
* <cTitlecolor> is the color with which to draw the box title. The
* default is yellow on red.
*
* <cBarcolor> is the color with which to draw the selection bar.
* The default is yellow on black.
*
* <cHkcolor> is the default color with which to draw the hotkeys for
* for each option. This is used when no hotkey color is supplied
* in <aArray>. The default is hiwhite on the current background
* color.
*
* <cShadow> is a character string, either "L" or "R" (for left or
* right) to designate the side of the box where a shadow will appear.
* Leave this NIL to avoid drawing a shadow. You might also leave
* this NIL if you choose to use a .C or .ASM shadow function, which
* is a good idea. Shadoww(), included below, is flat-out SLOW.
*
* <lExecute> turn on/off execution of option when first letter is
* pressed. Rule: setting in element 5 of each <aArray> subarray
* overrides <lExecute>. If that element is left NIL, the <lexecute>
* setting is used. If <lExecute> is not passed and element 5 is NIL,
* auto execution is turned ON by default.
*
* <nMsgrow> is the row on which to draw a message for each option.
* The default is two rows below the bottom of the box.
*
* <nMsgcol> is the column at which to draw a message for each option.
* The default is <nTopcol> +2.
*
* <cMsgcolor> is the default color with which to draw messages. This
* color is used when element 4 of each <aArray> subarray is left NIL.
* The default is Setcolor().
*
* <cElevbar> is the ASCII character to use as the elevator bar drawn
* on the box. Leave this NIL to draw no elevator bar.
*
* <cEbarcolor> is the color with which to draw the elevator bar.
* This is ignored if <cElevbar> is NIL.
*
* <cEbarside> is a character string, either "L" or "R" (for left or
* right) to designate the side of the box on which to draw the
* elevator bar. This is ignored if <cElevbar> is NIL.
*
* <cNoselcolor> is the color with which to draw unselectable options.
* The default is white on black.
*
* <cTagchar> is the ASCII character to use to draw tags that would
* appear to the right of each option. The default is DISabled
* tagging. The default tag is "√" (chr(251)).
*
* <nStartelem> is the number of the option where the selection bar
* will first be placed. Leave this NIL to begin at option 1.
*
* <lRestscrn> is a logical to designate whether or not the screen
* coordinates occupied by the box and/or shadow should be restored
* before FT_Ach2tb() returns. The default is .T.
*
* <nTimeout> is the number of seconds after which FT_ACH2TB() will
* timeout and return to the function/proced. which called it. The
* default is 0, or no timeout.
*
* <bUserfunc> is a code block containing a function call to be
* executed after each key press. You need to write just two formal
* parameters to allow the run-time passing of the key pressed and the
* current element number, e.g.:
*
* { | nKey, nElemnum | Myfunc( nKey, nElemnum [, xAnythingelse ] ) }
*
* Unlimited extra parameters may be passed. Of course, make certain
* to also write 'receptors' for them in 'Myfunc()' itself...as in the
* above example. The default is NO user function.
* $RETURNS$
* the number of the selected option, or 0 if [Esc] is pressed.
* $DESCRIPTION$
* FT_Ach2tb() is a greatly enhanced, fully featured replacement for
* Achoice(), based on a Tbrowse object. Each element of <aArray> needs
* to be composed as follows:
*
* Option , Message , HotKeyPos, HotKeyColor, Selectable
* { "Utilities","System Utilities", 3 , "+gr/b" , .T. }
*
* All elements except for the first, the option itself, are optional.
* IF 'Message' is NIL, no message is displayed. 'HotKeyPos' is the
* position within 'Option' of the hotkey. In the example above, the
* hotkey for 'Utilities' is the first 'i', i.e., at position 3. The
* default is 1. 'HotKeyColor' is the color to use for the hotkey
* display. The default is hiwhite on the current background color.
* 'Selectable' is a logical indicating whether or not that option can
* be selected. The default is .T.
*
* The A_CHOICE() UDC in FT_ACH2T.CH makes using FT_ACH2TB() a breeze.
* The myriad of parameters can be written in any order. Only <nToprow>,
* <nTopcol>, and <aArray> are required. See the example below.
*
* There may be some confusion over 'unselected' and 'unselectable'
* options. The former refers to any option not currently covered
* by the selection bar. The latter refers to options you have
* designated unselectable in subelement 5 of <aArray>, i.e., by
* writing .F.
*
* To enable tagging, pass any ASCII character as <cTagchar>. To
* tag/untag all options, press [SPACE]. To tag/untag individual
* options, press [+] and [-] respectively. To test for the tagged
* status of an option, use the WAS_TAGGED() UDC in FT_ACH2T.CH. To
* check the entire array for tags, use Aeval() in conjunction with
* Was_Tagged() as in the example below. When tagging is enabled, the
* string "Tags" will be written across the bottom row of the box in
* hiwhite on the current background color.
*
* Because FT_ACH2TB() takes over the [SPACE], [+], and [-] keys, it saves
* any SET KEY procedures you might have set them to, and restores same
* on returning. Any other procedures you might have SET KEYs to will
* fly when FT_ACH2TB() is called...thanks to the INKEY() replacement,
* SKINKEY().
*
* The piece de resistance of FT_ACH2TB() is its ability to execute
* a user function designed entirely by you. It is called after each
* keypress, and because it is completely open-ended, extends the
* the reach of FT_ACH2TB() to the limits of Clipper. See the docu-
* mentation under <bUserfunc> above.
*
* Test compile: CLIPPER ft_ach2t /n/w/m/dFT_TEST
* Test link : RTLINK fi ft_ach2t /pll:base50
*
* $EXAMPLES$
* nOpt := A_CHOICE( 7,9 ARRAY:t_array USERFUNC:{|a,b| UserFunc(a,b,any1)};
* BOXTYPE:B_SINGLE BOXTITLE:title SHADOW:"R" TAGCHAR:chr(17) ;
* REST_SCREEN:.F. AUTOEXEC:.F. MES_COLOR:MSG_COLOR ELEVBAR:"▒" ;
* NOSELCOLOR:"bg/n")
*
* Check only the RETURNed element:
* IF Was_Tagged(chr(17),t_array,nOpt); MoreProcessing(); END
*
* Check entire 't_array':
* Aeval( t_array,{|e,n| IF( Was_Tagged(chr(17),t_array,n ), ;
* MoreProcessing(t_array),NIL ) } )
* $INCLUDE$
* FT_ACH2T.CH
* $SEEALSO$
*
* $END$
*/
#include "inkey.ch"
#include "box.ch"
#include "setcurs.ch"
#include "ft_ach2t.ch"
#define KEY_ELEM 1
#define BLK_ELEM 2
#define AOPT 1
#define AMSG 2
#define AHOT 3
#define ACLR 4
#define ASEL 5
#define HOTKEY_PRESS (aelem > 0)
#define METHOD_PRESS (meth_num > 0 .and. meth_num <= 11)
#define TAGS ( tagchar<>NIL )
#define TAG_PRESS (TAGS .and. (meth_num > 11))
#define CONTINUING (lkey <> K_ESC)
#define OUTTA_HERE EXIT
#define ATTOP (aindex==1)
#define ATBOTT (aindex==Len(arrey))
#define USEL_COLOR FGColor(Setcolor())+"/"+BGColor(Setcolor())
#define BARCOLOR if(iscolor(),"+gr/n","n/w")
#define TITLECOLOR if(iscolor(),"+gr/r","n/w")
#define DEMOCOLOR if(iscolor(),"+gr/b","+w/n")
#define HK_COLOR if(iscolor(),"w+/"+ BGColor(setcolor()),"w+/n")
#define SELECTABLE (if(len(arrey[aindex])==5 .and. arrey[aindex][5]<> NIL,;
arrey[aindex][5],aexec))
#define NOSELECT (len(arrey[aindex])==5 .and. !(arrey[aindex][5]))
#define DEFAULT_TAG "√"
#define UP_ARROW_POS t+2,col4bar
#define DN_ARROW_POS b-2,col4bar
#define UP_ARROW if(top_elem > 1,chr(24),chr(25))
#define DN_ARROW if(bot_elem < num_elems,chr(25),chr(24))
#define GOING_UP (Ltrim(str(meth_num)) $ "13579")
#define GOING_DOWN (Ltrim(str(meth_num)) $ "2468 10")
#xtranslate DISPMSG(<r>,<c>,<msg>[,<color>]) => ;
SetPos(<r>,<c>); DispOut(<msg>[,<color>])
#translate Clear([<t>,<l>,<b>,<r>]) => ;
SCROLL([<t>,<l>,<b>,<r>])
#command DEFAULT <p> TO <val> [,<pn> TO <valn>] => ;
<p> := IF( <p> == NIL, <val>, <p>) ;
[;<pn> := IF( <pn> == NIL, <valn>, <pn>)]
#command STABILIZE <o> => WHILE !<o>:stabilize(); END
#ifndef K_SPACEBAR
#define K_SPACEBAR 32
#endif
#ifndef K_PLUS
#define K_PLUS 43
#define K_MINUS 45
#endif
STATIC msg_len:= 0,dir:= "D"
#ifdef FT_TEST
Function Test( passes )
// Item Msg HotKeyPos/HotkeyColor/Selectable
LOCAL t_arrey:= { {"Larry" ,"larry" , ,"w+/b" },;
{"Dick" ,"dick" , ,"b/r" },;
{"Harry" , , 3, ,.F. },;
{"Steve" ,"steve" , 4,"g/bg" },;
{"Michelle","michelle" },;
{"Barnabas", , 6,"gr+/w" },;
{"Fred" ,"fred" },;
{"Lisa" ,"lisa" , 3,"n/r" },;
{"Eleanor" ,"eleanor" , 4,"bg/r" },;
{"Anthony" ,"anthony" , 3 },;
{"Charles" ,"charles" , , ,.F. },;
{"Ollie" ,"ollie" , 4,"r/w" },;
{"George" , , 5 },;
{"Paula" ,"paula" },;
{"Jack" ,"jack" , 4 },;
{"Quinten" ,"quinten" },;
{"Nancy" ,"nancy" , 5,"w/n" },;
{"Warren" ,"warren" , 1,"n/gr*" } }
LOCAL t_arrey2:= {{"Warren" ,"warren" , ,"w+/b" },;
{"Charles" ,"charles" },;
{"Ollie" ,"ollie" , 4,"r/w" },;
{"George" , , 5 },;
{"Paula" ,"paula" , 3,"gr+/bg" },;
{"Harry" , , 3, ,.F. },;
{"Michelle","michelle" , ,"gr+/gr" },;
{"Anthony" ,"anthony" , 2 } }
LOCAL title:= " SK Test ",retval,xx,o_color:= Setcolor( DEMOCOLOR ),o_blink
LOCAL any1:= "User function called!",retval2
LOCAL any2:= "User function2 called!"
DEFAULT passes to 3; passes:= IF(valtype(passes)=="C",val(passes),passes)
Clear()
o_blink:= SetBlink(.F.)
FOR xx:= 1 to passes
retval:= A_CHOICE( 7,9 ARRAY:t_arrey TITLEPOS:2 START_ELEM:retval ;
USERFUNC:{|a,b| UserFunc(a,b,any1,.F.,1,.T.)} ;
BOXTYPE:B_SINGLE BOXTITLE:title SHADOW:"R" TAGCHAR:chr(17);
REST_SCREEN:.F. AUTOEXEC:.F. MES_COLOR:"+w/b" ELEVBAR:"▒" )
@ 1,0 say "Returned element "+Ltrim(str(retval))+" "
IF retval > 0
@ 2,0 say "That was "+IF( Was_Tagged(chr(17),t_arrey,retval) ,;
"a Tagged","an UNtagged")+" element "
END
@ 3,0 say "Press, Please "; inkey(0)
Clear()
retval2:= A_CHOICE( 5,9 ARRAY:t_arrey2 BOXTYPE:B_DOUBLE ELEVBAR:"░" ;
BOXTITLE:" SK Test2 " AUTOEXEC:.T. ELEVBAR_COLOR:"+w/r" ;
MES_COLOR:"+w/gr" USERFUNC:{|a,b| UserFunc(a,b,any2,.T.,3,.F.,4)} ;
REST_SCREEN:.F. ELEVBAR_SIDE:"R" TIME_OUT:4 ;
START_ELEM:3 SHADOW:"L" BAR_COLOR:"+r/gr*" )
@ 1,0 say "Returned element "+Ltrim(str(retval2))+" "
IF retval2 > 0
@ 2,0 say "That was "+IF( Was_Tagged(DEFAULT_TAG,t_arrey2,retval2) ,;
"a Tagged","an UNtagged")+" element "
END
@ 3,0 say "Press, Please "; inkey(0)
Clear()
NEXT
SetBlink(o_blink)
QUIT
RETURN NIL
#endif
FUNCTION FT_Ach2tb( t,l,b,r,arrey,boxtp,boxcolor,boxttl,ttlpos,uselcolor,;
ttlcolor,barcolor,hkcolor,shad,aexec,msg_row,msg_col,msg_color,;
ebar,ebarcolor,ebarside,noselcolor,tagchar,start_elem,r_screen,;
timeout,u_func )
LOCAL o_curs,lkey:= 0,meth_num:= 0,num_elems:= Len(arrey),ach_scrn,;
o_color,aelem:= 0,ex_req:= .F.,uf_cont:= .T.,top_elem,bot_elem,;
dm_color,o_blink,first_entry:= .T.,col4bar,didtag:=.F.,aindex, ;
a_chscrn,o_row:= Row(),o_col:= Col(),hotkeys[3],ab_methods,ab
DEFAULT boxtp TO B_DOUBLE, ttlcolor TO TITLECOLOR,;
barcolor TO BARCOLOR, r_screen TO .T. ,;
msg_col TO l+2, noselcolor TO "w/n" ,;
msg_color TO USEL_COLOR, boxcolor TO setcolor(),;
uselcolor TO USEL_COLOR, aexec TO .T. ,;
ebarcolor TO Setcolor(), ;
ebarside TO "L", start_elem TO 1 ,;
timeout TO 0, ttlpos TO 1
o_curs := SetCursor(SC_NONE)
SR_keys( "S",hotkeys )
IF b==NIL
b:= IF( (t+Len(arrey)+1) >= maxrow()-2,maxrow()-2,(t+Len(arrey)+1) )
END
DEFAULT msg_row TO b+2
r:= PrepArray( arrey,l,r,TAGS,tagchar )
ach_scrn := SaveScreen( t,l-2,b+2,r+2 )
aindex:= 1
ab:= tbrowsenew( t+1,l+1,b-1,r-1 )
ab:addcolumn(tbcolumnnew("",{|| arrey[aindex][AOPT]} ))
ab:getcolumn(1):width := (r-1 -l)
ab:gotopblock := {|| aindex := 1}
ab:gobottomblock := {|| aindex := num_elems}
ab:skipblock := {|num_elems| Askip( num_elems,@aindex,arrey )}
ab:colorspec += ","+uselcolor+","+barcolor+","+noselcolor
ab:getcolumn(1):colorblock:= { || ;
IF(NOSELECT,{8},{6}) ,;
ab:getcolumn(1):defcolor:= IF(NOSELECT,{8,8},{6,7}) }
ab_methods:= Curs_Methods()
PaintBox( t,l,b,r,boxtp,boxcolor,boxttl,ttlcolor,ttlpos,shad,TAGS )
col4bar := IF(upper(ebarside)=="L",l,r)
IF ebar <> NIL ; ElevBar( t+1,col4bar,b,ebar,ebarcolor,ebarside ); END
ab:autolite(.F.)
WHILE CONTINUING
DispBegin()
IF !ab:stable(); STABILIZE ab; END
IF NOSELECT; IF( dir=="U",ab:up(),ab:down() ); STABILIZE ab; END
top_elem:= 1+aindex-ab:rowpos; bot_elem:= top_elem+ab:rowcount-1
IF first_entry .and. start_elem > 1
HotKeyPress( ab,arrey,start_elem,aindex,top_elem,bot_elem )
aindex:= start_elem
top_elem:= 1+aindex-ab:rowpos; bot_elem:= top_elem+ab:rowcount-1
END
HotKeyColor( t,l,top_elem,arrey,ab:rowcount,hkcolor )
ab:hilite()
DispMsgg( msg_row,msg_col,arrey,aindex,msg_color )
IF ebar <> NIL
DispMsg( UP_ARROW_POS,UP_ARROW,ebarcolor )
DispMsg( DN_ARROW_POS,DN_ARROW,ebarcolor )
END
DispEnd()
// idle mode
IF valtype(u_func)=="B"; uf_cont:= Eval( u_func,lkey,aindex ); END
IF ex_req .or. !uf_cont; OUTTA_HERE; ELSE; lkey:= 0; END
************************************
lkey := SKInkey(timeout)
************************************
meth_num := Ascan( ab_methods, {|e| lkey == e[KEY_ELEM] })
aelem := Ascan( arrey,{|e| IF(Len(e) >= AHOT .and. e[AHOT]<>NIL,;
upper(chr(lkey)) == upper(subs(Ltrim(e[AOPT]),e[AHOT],1)) ,;
upper(chr(lkey)) == upper(left(Ltrim(e[AOPT]),1)) ) } )
IF HOTKEY_PRESS
HotKeyPress(ab,arrey,aelem,aindex,top_elem,bot_elem)
ex_req:= SELECTABLE; aindex:= aelem
ELSEIF METHOD_PRESS
ex_req:= Eval( ab_methods[meth_num][BLK_ELEM],ab,ATTOP,ATBOTT )
ex_req:= (ex_req .and. !NOSELECT)
dir := IF(GOING_UP,"D",IF(GOING_DOWN,"U",dir) )
ELSEIF TAG_PRESS
didtag:= TagPress( ab,arrey,aindex,lkey,tagchar )
ENDIF
IF lkey==0; ex_req:= .T.; END
first_entry:= .F.
ENDDO
Aeval( arrey,{|e| e[AOPT]:= Ltrim(e[AOPT]) } )
SetPos(o_row,o_col); SetCursor(o_curs)
IF r_screen; RestScreen( t,l-2,b+2,r+2,ach_scrn ); END
SR_keys( "R",hotkeys )
RETURN IF( lkey==K_ESC, 0, aindex )
************************************************************************
STATIC FUNCTION Askip(num_elems, aindex, arrey)
LOCAL save_aindex := aindex
aindex:= IF( aindex+num_elems > Len(arrey), Len(arrey),;
IF( aindex+num_elems < 1, 1, aindex+num_elems ))
RETURN (aindex - save_aindex)
*************************************************************************
STATIC FUNCTION HotKeyPress( ab,arrey,elem,aindex,top_elem,bot_elem )
LOCAL cur_elem:= aindex,new_elem:= elem,dest
WHILE cur_elem < new_elem // descending
dest:= MIN( new_elem,bot_elem ) ; dir:= "D"
WHILE cur_elem < dest; ab:down(); cur_elem++; END // speeding
STABILIZE ab
WHILE cur_elem < new_elem ; ab:down() ; STABILIZE ab; cur_elem++; END
END
WHILE cur_elem > new_elem // ascending
dest:= MAX( new_elem,top_elem ) ; dir:= "U"
WHILE cur_elem > dest; ab:up(); cur_elem--; END // speeding
STABILIZE ab
WHILE cur_elem > new_elem ; ab:up() ; STABILIZE ab; cur_elem--; END
END
RETURN NIL
*************************************************************************
STATIC FUNCTION DispMsgg( r,c,arrey,pos,msg_color )
LOCAL dm_color
IF msg_len > 0
Clear( r,c,r,(c+msg_len) )
END
IF Len(arrey[pos]) >= AMSG .and. arrey[pos][AMSG] <> NIL // if msg. to display
dm_color:= IF(Len(arrey[pos]) >= ACLR .and. arrey[pos][ACLR]<>NIL,;
arrey[pos][ACLR],msg_color)
DispMsg( r,c,arrey[pos][AMSG],dm_color )
msg_len:= Len(arrey[pos][AMSG])
END
RETURN NIL
*************************************************************************
/*
this is here for test purposes. the default is NO user func.
*/
#ifdef FT_TEST
FUNCTION UserFunc( key,elem_num,anything,aexec,st_elem,tag,tmout )
LOCAL ret_val:= .T.
DEFAULT tmout TO 0
@ 09,45 say " LASTKEY: "+Ltrim(str(key))+" "
@ 10,45 say "CURRENT ELEMENT NUM: "+Ltrim(str(elem_num))+" "
@ 11,45 say " AUTO-EXECUTION IS: "+if(aexec,"ON ","OFF")
@ 12,45 say "STARTING AT ELEMENT: "+ltrim(str(st_elem))
@ 13,45 say " TAGGING IS: "+if(tag,"ENABLED ","DISABLED")
@ 14,45 say " TIMEOUT: "+if(tmout >0,ltrim(str(tmout))+" secs. ",;
"INACTIVE ")
IF anything <> NIL; @ 16,45 say anything; END
/*
return .F. if you want to leave FT_ACH2TB() after whatever
processing you do here.
*/
RETURN (ret_val)
#endif
**************************************************************************
STATIC FUNCTION HotKeyColor( t,l,top_elem,arrey,rowcount,hkcolor )
LOCAL i:= 0,color2use,col2use,charpos
#define ELEM2USE arrey[top_elem+i]
#define CANT_SELECT (len(ELEM2USE)==5 .and. !ELEM2USE[ASEL])
Aeval( Array(rowcount),{|e,xx| ;
color2use:= IF( Len(ELEM2USE) >=ACLR .and. ELEM2USE[ACLR]<>NIL,;
ELEM2USE[ACLR], IF(hkcolor<>NIL,hkcolor,HK_COLOR) ),;
col2use:= IF(len(ELEM2USE) >=AHOT .and. ELEM2USE[AHOT]<>NIL,;
l+1+ELEM2USE[AHOT],l+2),;
charpos:= IF(len(ELEM2USE) >=AHOT .and. ELEM2USE[AHOT]<>NIL,;
ELEM2USE[AHOT],1 ) ,;
IF( !CANT_SELECT, SetPos( t+xx,col2use ),NIL) ,;
IF( !CANT_SELECT, ;
DispOut( SUBS(Ltrim(ELEM2USE[AOPT]),charpos,1),color2use ),NIL) ,;
i++ } )
RETURN NIL
****************************************************************************
STATIC FUNCTION Curs_Methods()
RETURN { ;
{K_DOWN, {|b,s,e| IF(e,b:gotop(), b:down()), .F. } }, ;
{K_UP, {|b,s,e| IF(s,b:gobottom(),b:up()), .F. } }, ;
{K_PGDN, {|b,s,e| IF(e,b:gotop(), b:pagedown()), .F. } }, ;
{K_PGUP, {|b,s,e| IF(s,b:gobottom(),b:pageup()), .F. } }, ;
{K_CTRL_PGUP,{|b,s,e| IF(s,b:gobottom(),b:gotop()), .F. } }, ;
{K_CTRL_PGDN,{|b,s,e| IF(e,b:gotop(), b:gobottom()), .F. } }, ;
{K_CTRL_HOME,{|b,s,e| IF(s,b:gobottom(),b:gotop()), .F. } }, ;
{K_CTRL_END, {|b,s,e| IF(e,b:gotop(), b:gobottom()), .F. } }, ;
{K_HOME, {|b,s,e| IF(s,b:gobottom(),b:gotop()), .F. } }, ;
{K_END, {|b,s,e| IF(e,b:gotop(), b:gobottom()), .F. } }, ;
{K_ENTER, {|b,s,e| .T. } }, ;
{K_SPACEBAR, {|b,s,e| .F. } }, ;
{K_PLUS, {|b,s,e| .F. } }, ;
{K_MINUS, {|b,s,e| .F. } } ;
}
****************************************************************************
STATIC FUNCTION ElevBar( t,col4bar,b,ebar,bcolor )
LOCAL c:= 0
Aeval( Array(b-t),{ |e,n| SetPos(t+c,col4bar),DispOut(ebar,bcolor),c++ })
RETURN NIL
****************************************************************************
#define TARGET arrey[pos][AOPT]
#define TAGGED (tagchar $TARGET)
#define AEV_TARG arrey[n][AOPT]
#define AEV_TAGD (tagchar $AEV_TARG)
STATIC FUNCTION TagPress( ab,arrey,pos,lkey,tagchar )
LOCAL didtag:= .F.
IF (lkey==K_PLUS .and. !TAGGED) .or. (lkey==K_MINUS .and. TAGGED)
TARGET:= IF( (lkey==K_PLUS .and. !TAGGED) ,;
Left(TARGET,Len(TARGET)-1)+tagchar ,;
IF( (lkey==K_MINUS .and. TAGGED) ,;
Strtran(TARGET,tagchar," ") ,;
TARGET ))
ab:refreshcurrent(); didtag:= .T.
ENDIF
IF lkey==K_SPACEBAR
IF !(Ascan(arrey,{|e| tagchar $ e[AOPT] }) > 0)
Aeval(arrey,{|e,n| AEV_TARG:= Left(AEV_TARG,Len(AEV_TARG)-1)+tagchar })
ELSE
Aeval(arrey,{|e,n| AEV_TARG:= Strtran(AEV_TARG,tagchar," ") })
END
ab:refreshall() ; didtag:= .T.
ENDIF
RETURN (didtag)
****************************************************************************
STATIC FUNCTION PaintBox( t,l,b,r,boxtp,boxcolor,boxttl,ttlcolor,ttlpos,shad,tags )
#translate CenterB( <b>,<l>,<r>,<msg>[,<color>] ) => ;
SetPos(<b>,(<l>+Int((<r>-<l> -Len(<msg>))/2) ) ) ;;
DispOut(<msg>[,<color>])
IF shad <> NIL; Shadoww( t,l,b,r,upper(shad) ); END
DispBox( t,l,b,r,boxtp,boxcolor )
IF boxttl <> NIL; DispMsg( t,(l+ttlpos),boxttl,ttlcolor ); END
IF tags .and. (r-l) >= 4
CenterB( b,l,r,"Tags","+w/"+BGColor(setcolor()) )
END
RETURN NIL
****************************************************************************
STATIC FUNCTION PrepArray( arrey,l,r,tags,tagchar )
Aeval( arrey,{|e| e[AOPT]:= " " +AllTrim( ;
IF(tags,StrTran(e[AOPT],tagchar),e[AOPT]) ) } )
IF r==NIL; r:= 0
Aeval( arrey,{|e| r:= MAX( r,Len(e[AOPT]) ) }); r+= IF( !tags,(l+2),(l+3) )
END
IF tags; Aeval( arrey,{|e| e[AOPT]:= Padr(e[AOPT],r-l-1) }) ; END
RETURN (r)
*****************************************************************************
STATIC FUNCTION BGColor( color )
LOCAL startpos:= AT("/",color)+1
LOCAL endpos:= IF( "," $ color,AT(",",color),len(color)+1 )
RETURN upper(subs( color,startpos,(endpos-startpos) ))
*****************************************************************************
STATIC FUNCTION FGColor( color )
RETURN upper(subs( color,1,AT("/",color)-1 ))
*****************************************************************************
STATIC FUNCTION SKInkey( num_secs ) // fake a wait state
LOCAL iblock,key:= 0,looping:= .T.
WHILE looping
key:= inkey( num_secs )
IF ( iblock := Setkey(key) ) <> NIL
Eval( iblock, procname(1), procline(1), readvar() )
ELSE; looping:= .F.
END
END
RETURN (key)
****************************************************************************
STATIC FUNCTION SR_Keys( action,hotkeys )
IF action=="S"
hotkeys[1] := Setkey(K_SPACEBAR) ; Setkey(K_SPACEBAR,NIL)
hotkeys[2] := Setkey(K_PLUS) ; Setkey(K_PLUS,NIL)
hotkeys[3] := Setkey(K_MINUS) ; Setkey(K_MINUS,NIL)
ELSEIF action=="R"
Setkey(K_SPACEBAR,hotkeys[1])
Setkey(K_PLUS,hotkeys[2])
Setkey(K_MINUS,hotkeys[3])
END
RETURN NIL
****************************************************************************
STATIC FUNCTION Shadoww( t,l,b,r,side )
LOCAL bx
DEFAULT side TO "R"
l+= IF(side=="R",2,-2); r+= IF(side=="R",2,-2)
bx:= SaveScreen( ++t,l,++b,r )
RestScreen( t,l,b,r,Transf( bx,Replic("x"+chr(8),len(bx)/2) ) )
RETURN NIL